package com.yhsoft.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yhsoft.common.service.Po.TokenUser;
import com.yhsoft.common.service.TokenService;
import com.yhsoft.common.utils.JwtUtil;
import com.yhsoft.sys.controller.Response.LoginOutVo;
import com.yhsoft.sys.controller.Response.UserInfoListOutVo;
import com.yhsoft.sys.controller.Response.UserInfoOutVo;
import com.yhsoft.sys.entity.Menu;
import com.yhsoft.sys.entity.User;
import com.yhsoft.sys.mapper.UserMapper;
import com.yhsoft.sys.mapper.UserRoleMapper;
import com.yhsoft.sys.service.IMenuService;
import com.yhsoft.sys.service.IUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author yyyyyyyh
 * @since 2023-08-30
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    private static final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private PasswordEncoder passwordEncoder;

    @Resource
    private JwtUtil jwtUtil;

    @Resource
    private UserRoleMapper userRoleMapper;

    @Resource
    private IMenuService menuService;

    @Override
    public LoginOutVo login(User user) {
        // 根据用户名查询
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, user.getUsername());
        User loginUser = this.baseMapper.selectOne(wrapper);
        // 结果不为空，并且密码和传入密码匹配，则生成token，并将用户信息存入redis
        if (loginUser != null && passwordEncoder.matches(user.getPassword(), loginUser.getPassword())) {
            // 暂时用UUID, 终极方案是jwt
            // String key = "user:" + UUID.randomUUID();
            // 存入redis
            //redisTemplate.opsForValue().set(key,loginUser,30, TimeUnit.MINUTES);
            TokenUser tokenUser = new TokenUser();
            BeanUtils.copyProperties(loginUser, tokenUser);
            // 创建jwt
            String token = jwtUtil.createToken(tokenUser);
            logger.info("PC用户登录token:" + token);
            return new LoginOutVo(token, loginUser.getSysType(), loginUser.getId(), loginUser.getRole(), loginUser.getUsername(), loginUser.getAvatar(), loginUser.getCompanyId());
        }
        return null;
    }

    @Override
    public UserInfoOutVo getUserInfo(String token) {
        // 根据token获取用户信息，redis
        //Object obj = redisTemplate.opsForValue().get(token);
        User loginUser = null;
        try {
            loginUser = jwtUtil.parseToken(token, User.class);

        } catch (Exception e) {
            e.printStackTrace();
        }
        if (loginUser != null) {
            //User loginUser = JSON.parseObject(JSON.toJSONString(obj),User.class);
            Map<String, Object> data = new HashMap<>();
            data.put("name", loginUser.getUsername());
            data.put("avatar", loginUser.getAvatar());

            // 角色
            List<String> roleList = this.baseMapper.getRoleNameByUserId(loginUser.getId());
            data.put("roles", roleList);

            // 权限列表
            List<Menu> menuList = menuService.getMenuListByUserId(loginUser);
            data.put("menuList", menuList);
            //return data;
            return new UserInfoOutVo(loginUser.getUsername(), loginUser.getAvatar(), roleList, menuList);
        }
        return null;
    }

    @Override
    public void logout(String token) {
        // redisTemplate.delete(token);
    }

    @Override
    @Transactional
    public void addUser(User user) {
        // 写入用户表
        this.baseMapper.insert(user);
        // 写入用户角色表
//        List<Integer> roleIdList = user.getRoleIdList();
//        if (roleIdList != null) {
//            for (Integer roleId : roleIdList) {
//                userRoleMapper.insert(new UserRole(null, user.getId(), roleId));
//            }
//        }
    }

    @Override
    public User getUserById(String id) {
        User user = this.baseMapper.selectById(id);
        if (user == null) {
            return null;
        }
//        LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(UserRole::getUserId, id);
//        List<UserRole> userRoleList = userRoleMapper.selectList(wrapper);
//
//        List<Integer> roleIdList = userRoleList.stream()
//                .map(userRole -> {
//                    return userRole.getRoleId();
//                })
//                .collect(Collectors.toList());
//        user.setRoleIdList(roleIdList);

        return user;
    }

    @Override
    public User getAdminUserByCompanyId(Integer id) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getCompanyId, id);
        wrapper.eq(User::getIsAdmin, 1);
        User user = this.baseMapper.selectOne(wrapper);
        return user;
    }

    @Override
    @Transactional
    public void updateUser(User user) {
        // 更新用户表
        this.baseMapper.updateById(user);
        // 清除原有角色
//        LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(UserRole::getUserId, user.getId());
//        userRoleMapper.delete(wrapper);
        // 暂时废弃 设置新的角色
//        List<Integer> roleIdList = user.getRoleIdList();
//        if (roleIdList != null) {
//            for (Integer roleId : roleIdList) {
//                userRoleMapper.insert(new UserRole(null, user.getId(), roleId));
//            }
//        }
    }

    @Override
    public void deleteUserById(String ids) {
        List<String> list = Arrays.asList(ids.split(","));
        list.forEach(a -> {
            this.baseMapper.deleteById(a);
        });
        // 清除原有角色
        // LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
        // wrapper.eq(UserRole::getUserId, id);
        // userRoleMapper.delete(wrapper);
    }

    public IPage<UserInfoListOutVo> getUserList(String username, String phone, Long pageNo, Long pageSize) {
        TokenUser userinfo = TokenService.getUserBytoken();
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasLength(username), User::getUsername, username);
        wrapper.like(StringUtils.hasLength(phone), User::getPhone, phone);
        wrapper.eq(User::getDeleted, 0);
        wrapper.eq(User::getCompanyId, userinfo.getCompanyId());
        wrapper.orderByAsc(User::getId);

        Page<UserInfoListOutVo> page = new Page<>(pageNo, pageSize);
        //this.page(page,wrapper);
        // IPage<UserInfoListOutVo> ipage = this.baseMapper.getListPageByConditions(page, wrapper);
        IPage<UserInfoListOutVo> ipage = this.baseMapper.getUserListPageByConditions(page, wrapper);
        return ipage;
    }
}
